//
//  UTime.cpp
//  UltraStarDeluxeIOS
//
//  Created by 李 杰军 on 12-7-14.
//  Copyright (c) 2012年 DoReiMi. All rights reserved.
//

#include <iostream>
#include "UTime.h"

TTime USTime;
TRelativeTimer VideoBGTimer;
Uint32 TimeNew;
Uint32 TimeOld;
float TimeSkip;
float TimeMid;
Uint32 TimeMidTemp;

const int cSDLCorrectionRatio = 1000;

void CountSkipTimeSet()
{
    TimeNew = SDL_GetTicks();
}

void CountSkipTime()
{
    TimeOld = TimeNew;
    TimeNew = SDL_GetTicks();
    TimeSkip = (float)(TimeNew - TimeOld) / cSDLCorrectionRatio;
}

void CountMidTime()
{
    TimeMidTemp = SDL_GetTicks();
    TimeMid = (float)(TimeMidTemp - TimeNew) / cSDLCorrectionRatio;
}

TTime::TTime()
{
    CountSkipTimeSet();
}

float TTime::GetTime()
{
    float result;
    result = (float)SDL_GetTicks() / cSDLCorrectionRatio;
    return result;
}

TRelativeTimer::TRelativeTimer()
{
    State = rtsStopped;
    AbsoluteTime = 0;
    RelativeTime = 0;
}

/**
 * Starts the timer.
 * If WaitForTrigger is false the timer will be started immediately.
 * If WaitForTrigger is true the timer will be started when a trigger event
 * occurs. A trigger event is a call of one of the Get-/SetTime() methods.
 * In addition the timer can be started by calling this method again with
 * WaitForTrigger set to false.
 */
void TRelativeTimer::Start(bool WaitForTrigger)
{
    switch (State)
    {
        case rtsStopped:
        case rtsPaused:
            if (WaitForTrigger)
                State = rtsWait;
            else {
                State = rtsRunning;
                AbsoluteTime = SDL_GetTicks();
            }
            break;
        case rtsWait:
            if (!WaitForTrigger)
            {
                State = rtsRunning;
                AbsoluteTime = SDL_GetTicks();
                RelativeTime = 0;
            }
            break;
        default:
            break;
    }
}

/**
 * Pauses the timer and leaves the counter untouched.
 */
void TRelativeTimer::Pause()
{
    if (State == rtsRunning)
    {
        RelativeTime = GetTime();
        State = rtsPaused;
    }
}

/**
 * Stops the timer and sets its counter to 0.
 */
void TRelativeTimer::Stop()
{
    if (State != rtsStopped)
    {
        State = rtsStopped;
        RelativeTime = 0;
    }
}

/**
 * Returns the current counter of the timer.
 * If WaitForTrigger was true in Start() the timer will be started
 * if it was not already running.
 */
float TRelativeTimer::GetTime()
{
    float result = 0;
    switch (State)
    {
        case rtsStopped:
        case rtsPaused:
            result = RelativeTime;
            break;
        case rtsRunning:
            result = RelativeTime + (float)(SDL_GetTicks() - AbsoluteTime) / cSDLCorrectionRatio;
            break;
        case rtsWait:
            // start triggered
            State = rtsRunning;
            AbsoluteTime = SDL_GetTicks();
            result = RelativeTime;
            break;
        default:
            break;
    }
    
    return result;
}

/**
 * Sets the counter of the timer.
 * If WaitForTrigger was true in Start() the timer will be started
 * if it was not already running.
 */
void TRelativeTimer::SetTime(float Time)
{
    RelativeTime = Time;
    AbsoluteTime = SDL_GetTicks();
    if (State == rtsWait)
        State = rtsRunning;
}

TRelativeTimerState TRelativeTimer::GetState()
{
    TRelativeTimerState result;
    result = State;
    return State;
}